package com.tools.common.container;

import com.tools.common.object.C;
import com.tools.common.object.Note;
import com.tools.common.object.ObjKit;

import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Set 接口的实现类枚举
 * 用于更方便灵活地构建 Set 集合
 * */
@Note("List 接口的实现类枚举，用于更方便灵活地构建 Set 集合")
public enum SetEnum {

    HASH(HashSet.class, "java.util.HashSet"),

    LINKED(LinkedHashSet.class, "java.util.LinkedHashSet"),

    TREE(TreeSet.class, "java.util.TreeSet"),

    COPY_WRITE(CopyOnWriteArraySet.class, "java.util.concurrent.CopyOnWriteArraySet"),

    CONCURRENT(ConcurrentHashSet.class, "com.tools.common.container.ConcurrentHashSet"),

    SKIP_LIST(ConcurrentSkipListSet.class, "java.util.concurrent.ConcurrentSkipListSet");

    @Note("Set 集合实现类的字节码")
    private final Class<?> implClass;

    @Note("Set 集合实现类的全限定类名")
    private final String implClassname;

    SetEnum(Class<?> implClass, String implClassname) {
        this.implClass = implClass;
        this.implClassname = implClassname;
    }

    public String getImplClassname() {
        return implClassname;
    }

    public Class<?> getImplClass() {
        return implClass;
    }

    @Override
    public String toString() {
        return implClassname;
    }

    @Note("获取入参数组的容量，按照 HashMap 集合的扩容算法，计算出最合理的初始化容量，尽可能地减少扩容次数")
    public static <T>int calcInitSize(T[] array) {
        if(array == null) return 0;
        int size = array.length;
        if(size == 0) return 0;
        int newSize = (int) (size / 0.75f + 1.0f);
        return Math.min(newSize, MapEnum.MAX_SIZE);
    }


    @Note("获取入参 Collection 集合的容量，按照 HashMap 集合的扩容算法，计算出最合理的初始化容量，尽可能地减少扩容次数")
    public static int calcInitSize(Collection c) {
        if(c == null) return 0;
        int size = c.size();
        if(size == 0) return 0;
        int newSize = (int) (size / 0.75f + 1.0f);
        return Math.min(newSize, MapEnum.MAX_SIZE);
    }

    @Note("获取入参自定义容器集合的容量，按照 HashMap 集合的扩容算法，计算出最合理的初始化容量，尽可能地减少扩容次数")
    public static int calcInitSize(OwnRows r) {
        if(r == null) return 0;
        int size = r.size();
        if(size == 0) return 0;
        int newSize = (int) (size / 0.75f + 1.0f);
        return Math.min(newSize, MapEnum.MAX_SIZE);
    }




    /* *******************************************************************************************
     *
     *          获取枚举实例
     *
     * *******************************************************************************************
     * */


    @Note("根据 implClassname 全路径获取映射的 SetEnum 实例")
    public static SetEnum getEnum(String implClassname) {
        if(HASH.implClassname.equalsIgnoreCase(implClassname)) {
            return HASH;
        }
        if(CONCURRENT.implClassname.equalsIgnoreCase(implClassname)) {
            return CONCURRENT;
        }
        if(LINKED.implClassname.equalsIgnoreCase(implClassname)) {
            return LINKED;
        }
        if(TREE.implClassname.equalsIgnoreCase(implClassname)) {
            return TREE;
        }
        if(SKIP_LIST.implClassname.equalsIgnoreCase(implClassname)) {
            return SKIP_LIST;
        }
        if(COPY_WRITE.implClassname.equalsIgnoreCase(implClassname)) {
            return COPY_WRITE;
        }
        return null;
    }


    @Note("根据 implClass 字节码获取映射的 SetEnum 实例")
    public static SetEnum getEnum(Class<?> implClass) {
        if(HASH.implClass.equals(implClass)) {
            return HASH;
        }
        if(LINKED.implClass.equals(implClass)) {
            return LINKED;
        }
        if(CONCURRENT.implClass.equals(implClass)) {
            return CONCURRENT;
        }
        if(TREE.implClass.equals(implClass)) {
            return TREE;
        }
        if(SKIP_LIST.implClass.equals(implClass)) {
            return SKIP_LIST;
        }
        if(COPY_WRITE.implClass.equals(implClass)) {
            return COPY_WRITE;
        }
        return null;
    }


    /* *******************************************************************************************
     *
     *          直接构建 Set 集合
     *
     * *******************************************************************************************
     * */


    @Note("根据枚举值构建不同实现类实现的 Set 集合")
    public <T> Set<T> newSet() {
        switch (this) {
            case HASH: return new HashSet<>();
            case LINKED: return new LinkedHashSet<>();
            case TREE: return new TreeSet<>();
            case CONCURRENT: return new ConcurrentHashSet<>();
            case SKIP_LIST: return new ConcurrentSkipListSet<>();
            default: return new CopyOnWriteArraySet<>();
        }
    }


    @Note("根据枚举值，用不同的实现类实现 Set 集合，如果是可以指定容量的则指定其初始化大小为 initSize")
    public <T>Set<T> newSet(int initSize) {
        switch (this) {
            case HASH: return (initSize == 0) ? new HashSet<>() : new HashSet<>(MapEnum.calcInitSize(initSize));
            case CONCURRENT: return (initSize == 0) ? new ConcurrentHashSet<>() : new ConcurrentHashSet<>(initSize);
            case LINKED: return (initSize == 0) ? new LinkedHashSet<>() : new LinkedHashSet<>(MapEnum.calcInitSize(initSize));
            case TREE: return new TreeSet<>();
            case SKIP_LIST: return new ConcurrentSkipListSet<>();
            default: return new CopyOnWriteArraySet<>();
        }
    }

    @Note("根据枚举值，用不同的实现类实现 Set 集合，如果实现类是 TreeSet 则默认指定入参的 Comparator 排序比较器")
    public <T>Set<T> newSet(Comparator<? super T> c) {
        switch (this) {
            case HASH: return new HashSet<>();
            case LINKED: return new LinkedHashSet<>();
            case CONCURRENT: return new ConcurrentHashSet<>();
            case TREE: return new TreeSet<>(c);
            case SKIP_LIST: return new ConcurrentSkipListSet<>(c);
            default: return new CopyOnWriteArraySet<>();
        }
    }


    @Note("根据枚举值，用不同的实现类实现 Set 集合，根据不同的实现类可选择不同的入参增强初始化操作")
    public <T>Set<T> newSet(int initSize, Comparator<? super T> c) {
        switch (this) {
            case HASH: return (initSize == 0) ? new HashSet<>() : new HashSet<>(MapEnum.calcInitSize(initSize));
            case CONCURRENT: return (initSize == 0) ? new ConcurrentHashSet<>() : new ConcurrentHashSet<>(initSize);
            case LINKED: return (initSize == 0) ? new LinkedHashSet<>() : new LinkedHashSet<>(MapEnum.calcInitSize(initSize));
            case TREE: return new TreeSet<>(c);
            case SKIP_LIST: return new ConcurrentSkipListSet<>(c);
            default: return new CopyOnWriteArraySet<>();
        }
    }

    @Note("根据枚举值，用不同的实现类实现 Set 集合，然后把数组里的数据拷贝到该 Set 集合里")
    @SafeVarargs
    public final <T>Set<T> newSet(T... array) {
        switch (this) {
            case HASH: return RowKit.toHashSet(array);
            case CONCURRENT: return new ConcurrentHashSet<>(array);
            case LINKED: return RowKit.toLinkedHashSet(array);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(array);
            case TREE: return RowKit.toTreeSet(array);
            default: return RowKit.toCopyOnWriteArraySet(array);
        }
    }


    @Note("根据枚举值用不同的实现类实现 Set 集合，然后把数组里的数据拷贝到该 Set 集合里，其中 TreeSet 会指定入参的排序比较器")
    @SafeVarargs
    public final <T>Set<T> newSet(Comparator<? super T> c, T... elements) {
        switch (this) {
            case HASH: return RowKit.toHashSet(elements);
            case LINKED: return RowKit.toLinkedHashSet(elements);
            case CONCURRENT: return new ConcurrentHashSet<>(elements);
            case TREE: return RowKit.toTreeSet(c, elements);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(c, elements);
            default: return RowKit.toCopyOnWriteArraySet(elements);
        }
    }


    @Note("根据枚举值，用不同的实现类实现 Set 集合，然后把可迭代容器里的数据拷贝到该 Set 集合里")
    public <T>Set<T> newSet(Iterable<? extends T> elements) {
        switch (this) {
            case HASH: return RowKit.toHashSet(elements);
            case CONCURRENT: return new ConcurrentHashSet<>(elements);
            case LINKED: return RowKit.toLinkedHashSet(elements);
            case TREE: return RowKit.toTreeSet(elements);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(elements);
            default: return RowKit.toCopyOnWriteArraySet(elements);
        }
    }


    @Note("根据枚举值，用不同的实现类实现 Set 集合，然后把可迭代容器里的数据拷贝到该 Set 集合里，其中 TreeSet 会指定入参的排序比较器")
    public <T>Set<T> newSet(Iterable<? extends T> elements, Comparator<? super T> c) {
        switch (this) {
            case HASH: return RowKit.toHashSet(elements);
            case CONCURRENT: return new ConcurrentHashSet<>(elements);
            case LINKED: return RowKit.toLinkedHashSet(elements);
            case TREE: return RowKit.toTreeSet(elements, c);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(elements, c);
            default: return RowKit.toCopyOnWriteArraySet(elements);
        }
    }


    @Note("根据枚举值，用不同的实现类实现 Set 集合，然后把 Collection 集合里的数据拷贝到该 Set 集合里")
    public <T>Set<T> newSet(Collection<? extends T> elements) {
        switch (this) {
            case HASH: return RowKit.toHashSet(elements);
            case LINKED: return RowKit.toLinkedHashSet(elements);
            case CONCURRENT: return new ConcurrentHashSet<>(elements);
            case TREE: return RowKit.toTreeSet(elements);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(elements);
            default: return RowKit.toCopyOnWriteArraySet(elements);
        }
    }

    @Note("根据枚举值，用不同的实现类实现 Set 集合，然后把 Collection 集合里的数据拷贝到该 Set 集合里")
    public <T>Set<T> newSet(Collection<? extends T> elements, Comparator<? super T> c) {
        switch (this) {
            case HASH: return RowKit.toHashSet(elements);
            case LINKED: return RowKit.toLinkedHashSet(elements);
            case CONCURRENT: return new ConcurrentHashSet<>(elements);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(elements, c);
            case TREE: return RowKit.toTreeSet(elements, c);
            default: return RowKit.toCopyOnWriteArraySet(elements);
        }
    }


    @Note("根据枚举值，用不同的实现类实现 Set 集合，然后把 Collection 集合里的数据拷贝到该 Set 集合里")
    public <T>Set<T> newSet(OwnRows<? extends T> elements) {
        switch (this) {
            case HASH: return RowKit.toHashSet(elements);
            case TREE: return RowKit.toTreeSet(elements);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(elements);
            case CONCURRENT: return new ConcurrentHashSet<>(elements);
            case LINKED: return RowKit.toLinkedHashSet(elements);
            default: return RowKit.toCopyOnWriteArraySet(elements);
        }
    }

    @Note("根据枚举值，用不同的实现类实现 Set 集合，然后把 Collection 集合里的数据拷贝到该 Set 集合里")
    public <T>Set<T> newSet(OwnRows<? extends T> elements, Comparator<? super T> c) {
        switch (this) {
            case HASH: return RowKit.toHashSet(elements);
            case TREE: return RowKit.toTreeSet(elements, c);
            case SKIP_LIST: return RowKit.toConcurrentSkipListSet(elements, c);
            case CONCURRENT: return new ConcurrentHashSet<>(elements);
            case LINKED: return RowKit.toLinkedHashSet(elements);
            default: return RowKit.toCopyOnWriteArraySet(elements);
        }
    }

    /* *******************************************************************************************
     *
     *          静态 ”字节码“ 构建 Set 集合
     *
     * *******************************************************************************************
     * */


    @Note("使用 Set 集合指定的实现类来构建出一个 Set 集合")
    public static <T>Set<T> newSet(Class<?> implClass) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet();
    }


    @Note("根据实现类的字节码得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，如果是可以指定容量的则指定其初始化大小为 initSize")
    public static <T>Set<T> newSet(Class<?> implClass, int initSize) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet(initSize);
    }


    @Note("根据实现类的字节码得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，" +
            "如果实现类是 TreeSet 则默认指定入参的 Comparator 排序比较器")
    public static <T>Set<T> newSet(Class<?> implClass, Comparator<? super T> c) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet(c);
    }


    @Note("根据实现类的字节码得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，" +
            "根据不同的实现类可选择不同的入参增强初始化操作")
    public static <T>Set<T> newSet(Class<?> implClass, int initSize, Comparator<? super T> c) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet(initSize, c);
    }


    @Note("根据实现类的字节码得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，接着把数组里的数据拷贝到内部")
    @SafeVarargs
    public static <T>Set<T> newSet(Class<?> implClass, T... array) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet(array);
    }

    @Note("根据实现类的字节码得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，接着把数组里的数据拷贝到内部，" +
            "如果实现类是 TreeSet 则指定该比较器")
    @SafeVarargs
    public static <T>Set<T> newSet(Class<?> implClass, Comparator<? super T> c, T... array) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet(c, array);
    }

    @Note("根据实现类的字节码得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，然后把可迭代容器里的数据拷贝到该 Set 集合里")
    public static <T>Set<T> newSet(Class<?> implClass, Iterable<? extends T> iterable) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet(iterable);
    }


    @Note("根据实现类的字节码得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，然后把可迭代容器里的数据拷贝到该 Set 集合里，" +
            "其中 TreeSet 会指定入参的排序比较器")
    public static <T>Set<T> newSet(Class<?> implClass, Comparator<? super T> c, Iterable<? extends T> iterable) {
        return private_getEnumIfNotExistsThrowException(implClass).newSet(iterable, c);
    }


    /* *******************************************************************************************
     *
     *              静态 ”全路径“ 构建 Set 集合
     *
     * *******************************************************************************************
     * */


    @Note("使用 Set 集合指定的实现类来构建出一个 Set 集合")
    public static <T>Set<T> newSet(String classname) {
        return private_getEnumIfNotExistsThrowException(classname).newSet();
    }


    @Note("根据实现类的全路径得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，如果是可以指定容量的则指定其初始化大小为 initSize")
    public static <T>Set<T> newSet(String classname, int initSize) {
        return private_getEnumIfNotExistsThrowException(classname).newSet(initSize);
    }


    @Note("根据实现类的全路径得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，" +
            "如果实现类是 TreeSet 则默认指定入参的 Comparator 排序比较器")
    public static <T>Set<T> newSet(String classname, Comparator<? super T> c) {
        return private_getEnumIfNotExistsThrowException(classname).newSet(c);
    }


    @Note("根据实现类的全路径得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，" +
            "根据不同的实现类可选择不同的入参增强初始化操作")
    public static <T>Set<T> newSet(String classname, int initSize, Comparator<? super T> c) {
        return private_getEnumIfNotExistsThrowException(classname).newSet(initSize, c);
    }


    @Note("根据实现类的全路径得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，接着把数组里的数据拷贝到内部")
    @SafeVarargs
    public static <T>Set<T> newSet(String classname, T... array) {
        return private_getEnumIfNotExistsThrowException(classname).newSet(array);
    }

    @Note("根据实现类的全路径得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，接着把数组里的数据拷贝到内部，" +
            "如果实现类是 TreeSet 则指定该比较器")
    @SafeVarargs
    public static <T>Set<T> newSet(String classname, Comparator<? super T> c, T... array) {
        return private_getEnumIfNotExistsThrowException(classname).newSet(c, array);
    }

    @Note("根据实现类的全路径得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，然后把可迭代容器里的数据拷贝到该 Set 集合里，")
    public static <T>Set<T> newSet(String classname, Iterable<? extends T> iterable) {
        return private_getEnumIfNotExistsThrowException(classname).newSet(iterable);
    }


    @Note("根据实现类的全路径得到映射的枚举值，然后构造出对应实现类实现的 Set 集合，然后把可迭代容器里的数据拷贝到该 Set 集合里，" +
            "其中 TreeSet 会指定入参的排序比较器")
    public static <T>Set<T> newSet(String classname, Comparator<? super T> c, Iterable<? extends T> iterable) {
        return private_getEnumIfNotExistsThrowException(classname).newSet(iterable, c);
    }

    /* *******************************************************************************************
     *
     *          反射构建 Set 集合
     *
     * *******************************************************************************************
     * */

    @Note("根据类型包装对象构建出指定初始化容量的 Set 集合")
    public static Set buildSet(C<?> setType, int initSize) {
        return private_buildSetByC(setType, initSize);
    }

    @Note("根据类型包装对象构建出 Set 集合，然后把 Collection 的数据按要求拷贝进去")
    public static Set buildSet(C<?> setType, Collection cs) {
        Set result = private_buildSetByC(setType, cs.size());
        if(result.isEmpty()) return result;
        C<?> componentType = setType.generic(0);
        if(componentType == null) {
            result.addAll(cs);
            return result;
        }
        for(Object o : cs) {
            result.add(ObjKit.toRealValue(o, componentType));
        }
        return result;
    }


    @Note("根据类型包装对象构建出 Set 集合，然后把自定义集合容器的数据按要求拷贝进去")
    public static Set buildSet(C<?> setType, OwnRows row) {
        Set result = private_buildSetByC(setType, row.size());
        if(result.isEmpty()) return result;
        C<?> componentType = setType.generic(0);
        if(componentType != null) {
            for(Object o : row) {
                result.add(ObjKit.toRealValue(o, componentType));
            }
            return result;
        }
        for (Object o : row) {
            result.add(o);
        }
        return result;
    }

    @Note("根据类型包装对象构建出 Set 集合，然后把可迭代容器内的数据按要求拷贝进去")
    public static Set buildSet(C<?> setType, Iterable elements) {
        if(elements instanceof Collection) return buildSet(setType, (Collection) elements);
        if(elements instanceof OwnRows) return buildSet(setType, (OwnRows) elements);
        Set result = private_buildSetByC(setType, RowKit.getIterableSize(elements));
        if(result.isEmpty()) return result;
        C<?> componentType = setType.generic(0);
        if(componentType == null) {
            for (Object o : elements) {
                result.add(o);
            }
        }
        else {
            for(Object o : elements) {
                Object value = ObjKit.toRealValue(o, componentType);
                result.add(value);
            }
        }
        return result;
    }

    @Note("根据类型包装对象构建出 Set 集合，然后把数组内的数据按要求拷贝进去")
    public static Set buildSet(C<?> setType, Object array) {
        if(array == null || !array.getClass().isArray()) {
            return private_buildSetByC(setType, 0);
        }
        int length = Array.getLength(array);
        Set result = private_buildSetByC(setType, length);
        C<?> componentType = setType.generic(0);
        if(componentType == null) {
            for (int i = 0 ; i < length ; i++) {
                result.add(Array.get(array, i));
            }
        }
        for (int i = 0; i < length; i++) {
            Object o = Array.get(array, i);
            result.add(ObjKit.toRealValue(o, componentType));
        }
        return result;
    }

    /* *******************************************************************************************
     *
     *          私有逻辑
     *
     * *******************************************************************************************
     * */


    @Note("根据 Set 集合实现类的字节码获取枚举映射的实例，如果获取不到则抛出异常")
    private static SetEnum private_getEnumIfNotExistsThrowException(Class<?> implClass) {
        if(Collection.class.equals(implClass) || Set.class.equals(implClass)) {
            return HASH;
        }
        SetEnum setEnum = getEnum(implClass);
        if(setEnum == null) throw new IllegalArgumentException("【" + implClass + "】 构建 Set 集合失败，请检查是否" +
                "存在该字节码映射的枚举实例");
        return setEnum;
    }


    @Note("根据 Set 集合实现类的全路径获取枚举映射的实例，如果获取不到则抛出异常")
    private static SetEnum private_getEnumIfNotExistsThrowException(String classname) {
        if("java.util.Collection".equals(classname) || "java.util.Set".equals(classname)) {
            return HASH;
        }
        SetEnum setEnum = getEnum(classname);
        if(setEnum == null) throw new IllegalArgumentException("【" + classname + "】 构建 Set 集合失败，请检查是否" +
                "存在该全路径映射的枚举实例");
        return setEnum;
    }


    @Note("通过类型包装对象构建一个 java.util.Set 集合对象")
    private static Set private_buildSetByC(C<?> c, int setSize) {
        Class<?> mainType = c.getMainType();
        //HashSet
        if(Set.class.equals(mainType) || HashSet.class.equals(mainType)) {
            if(c.argCount() == 0) {
                return (setSize <= 0) ? new HashSet<>() : new HashSet<>(MapEnum.calcInitSize(setSize));
            }
            Object first = c.getArgValue(0);
            if(first instanceof Number) {
                int initSize = ((Number) first).intValue();
                Object second = c.getArgValue(1);
                if((second instanceof Float) || (second instanceof Double)) {
                    return new HashSet<>(MapEnum.calcInitSize(initSize), ((Number) second).floatValue());
                }
                return new HashSet<>(MapEnum.calcInitSize(initSize));
            }
            if(first instanceof Collection) {
                return new HashSet<>((Collection<?>) first);
            }
            return (setSize <= 0) ? new HashSet<>() : new HashSet<>(MapEnum.calcInitSize(setSize));
        }
        //LinkedHashSet
        if(LinkedHashSet.class.equals(mainType)) {
            if(c.argCount() == 0) {
                return (setSize <= 0) ? new LinkedHashSet<>() : new LinkedHashSet<>(MapEnum.calcInitSize(setSize));
            }
            Object first = c.getArgValue(0);
            if(first instanceof Number) {
                int initSize = ((Number) first).intValue();
                Object second = c.getArgValue(1);
                if((second instanceof Float) || (second instanceof Double)) {
                    return new LinkedHashSet<>(MapEnum.calcInitSize(initSize), ((Number) second).floatValue());
                }
                return new LinkedHashSet<>(MapEnum.calcInitSize(initSize));
            }
            if(first instanceof Collection) {
                return new LinkedHashSet<>((Collection<?>) first);
            }
            return (setSize <= 0) ? new LinkedHashSet<>() : new LinkedHashSet<>(MapEnum.calcInitSize(setSize));
        }
        //ConcurrentHashSet
        if(ConcurrentHashSet.class.equals(mainType)) {
            if(c.argCount() == 0) {
                return (setSize <= 0) ? new ConcurrentHashSet<>() : new ConcurrentHashSet<>(setSize);
            }
            Object first = c.getArgValue(0);
            if(first instanceof Number) {
                int initSize = ((Number) first).intValue();
                Object second = c.getArgValue(1);
                if((second instanceof Float) || (second instanceof Double)) {
                    float load = ((Number) second).floatValue();
                    Object third = c.getArgValue(2);
                    if(third instanceof Number) {
                        int level = ((Number) third).intValue();
                        return new ConcurrentHashSet<>(initSize, load, level);
                    }
                    return new ConcurrentHashSet<>(initSize, load);
                }
                return new ConcurrentHashSet<>(initSize);
            }
            if(first.getClass().isArray()) {
                int length = Array.getLength(first);
                if(length == 0) return new ConcurrentHashSet<>();
                ConcurrentHashSet results = new ConcurrentHashSet<>(length);
                for (int i = 0; i < length; i++) {
                    results.add(Array.get(first, i));
                }
                return results;
            }
            if(first instanceof Collection) {
                return new ConcurrentHashSet<>((Collection<?>) first);
            }
            if(first instanceof OwnRows) {
                return new ConcurrentHashSet<>((OwnRows<?>) first);
            }
            if(first instanceof Iterable) {
                return new ConcurrentHashSet<>((Iterable<?>) first);
            }
            return (setSize <= 0) ? new ConcurrentHashSet<>() : new ConcurrentHashSet<>(setSize);
        }
        //TreeSet
        if(TreeSet.class.equals(mainType)) {
            if(c.argCount() == 0) return new TreeSet<>();
            Object first = c.getArgValue(0);
            if(first instanceof Comparator) return new TreeSet<>((Comparator) first);
            if(first instanceof Collection) return new TreeSet<>((Collection<?>) first);
            return new TreeSet<>();
        }
        //ConcurrentSkipListSet
        if(ConcurrentSkipListSet.class.equals(mainType)) {
            if(c.argCount() == 0) return new ConcurrentSkipListSet<>();
            Object first = c.getArgValue(0);
            if(first instanceof Comparator) return new ConcurrentSkipListSet<>((Comparator) first);
            if(first instanceof Collection) return new ConcurrentSkipListSet<>((Collection<?>) first);
            return new TreeSet<>();
        }
        //CopyOnWriteArraySet
        if(CopyOnWriteArraySet.class.equals(mainType)) {
            if(c.argCount() == 0) return new CopyOnWriteArraySet<>();
            Object first = c.getArgValue(0);
            if(first instanceof Collection) return new CopyOnWriteArraySet<>((Collection<?>) first);
            return new CopyOnWriteArraySet<>();
        }
        return (Set) ObjKit.buildObject(c);
    }
}
